//
//  RxMoyaRequestViewController.swift
//  DemoProject
//
//  Created by Hao on 2018/8/29.
//  Copyright © 2018年 hao. All rights reserved.
//

import UIKit

// MARK: 封装网络请求
fileprivate class DouBanNetworkService {
    
    //获取频道数据
//    func loadChannels() -> Observable<[DouBanChannelModel]> {
//        return DouBanProvider.rx.request(.channels)
//                .map{ $0.channels ?? [] }
//                .asObservable()
//    }
    
    //获取歌曲列表数据
    func loadPlaylist(channelId: String) -> Observable<[DouBanSongModel]> {
        return DouBanProvider.rx.request(.playlist(channelId))
            .mapString()
            .map({ (response) -> [DouBanSongModel] in
                if let songs = DouBanPlaylistModel.deserialize(from: response)?.song {
                    return songs
                }
                return [DouBanSongModel]()
            })
            .asObservable()
    }
    
    //获取频道下第一首歌曲
//    func loadFirstSong(channelId:String) -> Observable<Song> {
//        return loadPlaylist(channelId: channelId)
//            .filter{ $0.song.count > 0}
//            .map{ $0.song[0] }
//    }
    
}

// MARK: 控制器
class RxMoyaRequestViewController: BaseViewController {

    var disposeBag = DisposeBag()
    
    var tableView: UITableView!
    
    fileprivate var songsModelArr = [DouBanSongModel]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView = UITableView(frame: self.view.bounds, style: .plain)
        self.view.addSubview(tableView)
        tableView.top = kStatusBarAndNaviHeight()
        tableView.height = self.view.height-tableView.top
//        _requestDataMapObjectBindView()
        _requestDataPackage()
        
//        DouBanProvider.rx.request(.playlist("201")).subscribe(onSuccess: { (response) in
//            // 数据处理
//            let str = String(data: response.data, encoding: String.Encoding.utf8)
//            print(info: "返回的数据是：\(str ?? "none")")
//        }) { (error) in
//            print(info: "error -> \(error)")
//        }.disposed(by: disposeBag)
    }
    
    /// 将网络请求的结果转化为模型对象
    private func _requestDataMapObjectBindView() {
        DouBanProvider.rx.request(.playlist("201")).asObservable()
//            .mapObject(obj: DouBanPlaylistModel.self)
//            .map { (listModel) -> [DouBanSongModel] in
//                if let songs = listModel?.song {
//                    return songs
//                }
//                return [DouBanSongModel]()
//            }
            .mapString()
            .map({ [weak self] (response) -> [DouBanSongModel] in
                if let songs = DouBanPlaylistModel.deserialize(from: response)?.song {
                    self!.songsModelArr.append(contentsOf: songs)
                }
                return self!.songsModelArr
            })
            .bind(to: tableView.rx.items) { (tableView, row, songModel) -> UITableViewCell in
                var cell = tableView.dequeueReusableCell(withIdentifier: "RxMoyaRequestCell")
                if cell == nil {
                    cell = UITableViewCell(style: .default, reuseIdentifier: "RxMoyaRequestCell")
                }
                cell?.textLabel?.text = songModel.albumtitle
                return cell!
            }
            .disposed(by: disposeBag)
    }
    
    fileprivate var count = 0
    /// 调用 网络请求封装 对象
    private func _requestDataPackage() {
        DouBanNetworkService().loadPlaylist(channelId: "201")
            .map({ [weak self] (songs) -> [DouBanSongModel] in
                self!.songsModelArr = songs
                return self!.songsModelArr
            })
            .bind(to: tableView.rx.items) { [weak self] (tableView, row, songModel) -> UITableViewCell in
                var cell = tableView.dequeueReusableCell(withIdentifier: "RxMoyaRequestCell")
                if cell == nil {
                    cell = UITableViewCell(style: .value1, reuseIdentifier: "RxMoyaRequestCell")
                }
                cell?.textLabel?.text = songModel.albumtitle
                print(info: "调用 \(self!.count) 次")
                self!.count += 1
                if let detailTextLabel = cell?.detailTextLabel {
                    songModel.testObervable.asObservable().bind(to: detailTextLabel.rx.text).disposed(by: self!.disposeBag)
                }
                return cell!
            }
            .disposed(by: disposeBag)
        
        Observable<Int>.timer(5, scheduler: MainScheduler.instance).subscribe(onNext: { [weak self] _ in
            print(info: "-----")
            if let songModel = self!.songsModelArr.first {
                songModel.testObervable.accept("5秒后更改的新值")
            }
        }).disposed(by: disposeBag)
    }

}

extension Observable  {
    
    func mapObject<T : JSONProtocol>(obj: T.Type) -> Observable<T?> {
        return self.map { (element) -> T? in
            var value: T?
            if element is Data {
                let data = element as! Data
                print(info: "data -> \(String(data: data, encoding: String.Encoding.utf8) ?? "")")
                value = T.deserialize(from: String(data: data, encoding: String.Encoding.utf8))
            } else if element is String {
                value = T.deserialize(from: element as? String)
            } else if element is [String : Any] {
                value = T.deserialize(from: element as? [String : Any])
            } else if element is NSDictionary {
                value = T.deserialize(from: element as? NSDictionary)
            }
            return value
        }
    }
    
}

// MARK: 定义模型
fileprivate struct DouBanChannelModel : JSONProtocol {
    var abbr_en: String?
    var channel_id: Int?
    var name: String?
    var name_en: String?
}

fileprivate struct DouBanPlaylistModel : JSONProtocol {
    
    var r: Int?
    var isShowQuickStart: Int?
    var song: [DouBanSongModel]?
    
    mutating func mapping(mapper: HelpingMapper) {
        mapper <<<
            self.isShowQuickStart <-- "is_show_quick_start"
    }
    
}

fileprivate struct DouBanSongModel : JSONProtocol {
    
    var artist: String?
    var ssid: Int?
    var album: String?
    var formatModel: DouBanAvailableFormatsModel?
    var albumtitle: String?
    var testObervable = BehaviorRelay(value: "初始值")
    
    mutating func mapping(mapper: HelpingMapper) {
        mapper <<<
            self.formatModel <-- "available_formats"
    }
    
}

fileprivate struct DouBanAvailableFormatsModel : JSONProtocol {
    
    var sixFour: Int?
    var oneTwoEight: Int?
    
    mutating func mapping(mapper: HelpingMapper) {
        mapper <<<
            self.sixFour <-- "64"
        
        mapper <<<
            self.oneTwoEight <-- "128"
    }
}

/** {
 "all_play_sources": [{
 "confidence": 0.937778,
 "source_full_name": "itunes",
 "file_url": null,
 "source": "it",
 "source_id": "275878638",
 "playable": false,
 "page_url": null
 }],
 "albumtitle": "Great God Who Saves",
 "url": "http:\/\/mr3.doubanio.com\/a397f40c1b63a792deca9d4830156cc6\/0\/fm\/song\/p1548177_128k.mp4",
 "file_ext": "mp4",
 "album": "\/subject\/3221896\/",
 "ssid": "3261",
 "title": "Grace",
 "sid": "1548177",
 "sha256": "a8a071d1eff6a4628b2bf787d95ed74e32c2223e60e47dd6d0a38b921ca2e03d",
 "status": 0,
 "picture": "https://img1.doubanio.com\/view\/subject\/m\/public\/s3266169.jpg",
 "update_time": 1470126236,
 "alert_msg": "",
 "is_douban_playable": true,
 "public_time": "2008",
 "partner_sources": [],
 "singers": [{
 "style": [],
 "name": "Laura Story",
 "region": ["美国"],
 "name_usual": "Laura Story",
 "genre": ["Pop"],
 "avatar": "https://img3.doubanio.com\/img\/fmadmin\/large\/904891.jpg",
 "related_site_id": 0,
 "is_site_artist": false,
 "id": "47259"
 }],
 "like": 0,
 "artist": "Laura Story",
 "is_royal": false,
 "subtype": "",
 "length": 275,
 "release": {
 "link": "https:\/\/douban.fm\/album\/3221896g6e57",
 "id": "3221896",
 "ssid": "6e57"
 },
 "aid": "3221896",
 "kbps": "128",
 "available_formats": {
 "64": 2180,
 "128": 4275
 }
 },  */
